// import 'package:flutter/material.dart';
/**
 * Dart 库
 * dart:core
 * 内置类型，集合和其他核心功能。该库会被自动导入到所有的 Dart 程序。
 * 
 * dart:async
 * 支持异步编程，包括Future和Stream等类。
 * 
 * dart:math
 * 数学常数和函数，以及随机数生成器。
 */

/**
 * dart:core - 数字，集合，字符串等
 * 1.控制台打印
 * 顶级 print() 方法
 * 
 * 2.数字 num ，int 以及 double 类
 * int 和 double 的 parse() 方法将字符串转换为整型或双浮点型对象：
 * num 的 parse() 方法
 * 通过添加 radix 参数，指定整数的进制基数：
 * assert(int.parse('42', radix: 16) == 66);
 * // 整型转换为字符串类型。
 * assert(42.toString() == '42');
 * 双浮点型转换为字符串类型。
 * assert(123.456.toString() == '123.456');
 * 指定小数点后的位数。
 * assert(123.456.toStringAsFixed(2) == '123.46');
 * 指定有效数字的位数。
 * assert(123.456.toStringAsPrecision(2) == '1.2e+2');
 * assert(double.parse('1.2e+2') == 120.0);
 * 
 * 3.字符和正则表达式
 * 在字符串中搜索
 * 从字符串中提取数据
 * var codeUnitList ='Never odd or even'.codeUnits.toList();
 * assert(codeUnitList[0] == 78);
 * 
 * 4.首字母大小写转换
 * toUpperCase 转换为首字母大写。
 * toLowerCase 转换为首字母小写。
 * 5.Trimming 和空字符串
 * 使用 trim() 移除首尾空格。 使用 isEmpty 检查一个字符串是否为空（长度为0）。isNotEmpty 空格字符串不是空字符串。
 * 
 * 6.替换部分字符串
 *  replaceAll() 返回一个新字符串， 并没有改变原始字符串：
 * 7.构建一个字符串
 * 
 * 8.正则表达式
 * 
 * 9.集合
 * (1)Lists 可以通过字面量来创建和初始化 也可以使用 List 的构造函数
 * var vegetables = List(); 构造函数
 * var fruits = ['apples', 'oranges']; 字面量来创建和初始化
 * 添加元素 add('') addAll(['',''])
 * 移除一个元素 removeAt(index)
 * 移除多个元素 clear();
 * list 是参数化类型， 因此可以指定 list 应该包含的元素类型：var fruits = List<String>();
 * (2)Sets set 是一个无序的，元素唯一的集合
 * contains('') 和 containsAll(['','']) 来检查一个或多个元素是否在 set 中。
 * 交集 A.intersection(B)
 * (3)Maps map 是一个无序的 key-value （键值对）集合，就是大家熟知的 dictionary 或者 hash。 map 将 kay 与 value 关联，以便于检索。和 JavaScript 不同，Dart 对象不是 map 。
 * var nobleGases = Map<int, String>(); // 可以指定一个 map 中 key 和 value 的类型。
 * assert(nobleGases.containsKey(54)); 检查 map 是否包含 key 。
 * nobleGases.remove(54);  移除一个 key 及其 value。
 * var keys = hawaiianBeaches.keys; 获取的所有的 key 是一个无序集合
 * var values = hawaiianBeaches.values; 获取的所有的 value 是一个无序集合
 * 如果当且仅当该 key 不存在于 map 中，且要为这个 key 赋值， 可使用putIfAbsent（）方法。 该方法需要一个方法返回这个 value 。
 * var teamAssignments = {};teamAssignments.putIfAbsent('Catcher', () => pickToughestKid());
 * 
 * 10.公共集合方法
 * 
 * 11.URI
 * 编码和解码完整合法的URI
 * 使用 encodeFull() 和 decodeFull() 方法， 对 URI 中除了特殊字符（例如 /， :， &， #）以外的字符进行编解码， 这些方法非常适合编解码完整合法的 URI，并保留 URI 中的特殊字符。
 * var uri = 'http://example.org/api?foo=some message';
  var encoded = Uri.encodeFull(uri);
  assert(encoded =='http://example.org/api?foo=some%20message');
  var decoded = Uri.decodeFull(encoded);
  assert(uri == decoded);
 * 编码和解码 URI 组件
 * 使用 encodeComponent() 和 decodeComponent() 方法， 对 URI 中具有特殊含义的所有字符串字符，特殊字符包括（但不限于）/， &， 和 :。
 * var uri = 'http://example.org/api?foo=some message';
   var encoded = Uri.encodeComponent(uri);
   assert(encoded =='http%3A%2F%2Fexample.org%2Fapi%3Ffoo%3Dsome%20message');
   var decoded = Uri.decodeComponent(encoded);
   assert(uri == decoded);
 * 解析 URI
 * 使用 Uri 对象的字段（例如 path）， 来获取一个 Uri 对象或者 URI 字符串的一部分。 使用 parse() 静态方法，可以使用字符串创建 Uri 对象。
 * var uri =Uri.parse('http://example.org:8080/foo/bar#frag');
  assert(uri.scheme == 'http');
  assert(uri.host == 'example.org');
  assert(uri.path == '/foo/bar');
  assert(uri.fragment == 'frag');
  assert(uri.origin == 'http://example.org:8080');
 * 构建 URI
 * var uri = Uri(
  scheme: 'http',
  host: 'example.org',
  path: '/foo/bar',
  fragment: 'frag');
  assert(uri.toString() == 'http://example.org/foo/bar#frag');
 * 
 * 12.日期和时间
 * DateTime 对象可以通过若干构造函数创建：
 * var now = DateTime.now(); 获取当前时刻。
 * y2k = DateTime.utc(2000); // 1/1/2000, UTC 将日期指定为 UTC 时区。
 * y2k = DateTime.fromMillisecondsSinceEpoch(946684800000,isUtc: true); 指定自Unix纪元以来，以毫秒为单位的日期和时间。
 * y2k = DateTime.parse('2000-01-01T00:00:00Z'); 解析ISO 8601日期。
 * 使用 Duration 类来计算两个日期的查
 * var y2k = DateTime.utc(2000);
 * var y2001 = y2k.add(const Duration(days: 366));  增加一年。add
 * var december2000 =y2001.subtract(const Duration(days: 30)); 减少30天。subtract
 * A.difference(B) 计算两个时刻之间的查，
 * 
 * 13.工具类
 * 比较对象
 * 迭代
 * 异常 
 *  NoSuchMethodError 当方法的接受对象（可能为null）没有实现该方法时抛出。
 *  ArgumentError 当方法在接受到一个不合法参数时抛出。
 * 
 */

// 重写 hashCode 的 getter 方法来生成自定义哈希值
class Person {
  final String firstName, lastName;

  Person(this.firstName, this.lastName);

  // 重写 hashCode，实现策略源于  Effective Java，
  // 第11章。
  @override
  int get hashCode {
    int result = 17;
    result = 37 * result + firstName.hashCode;
    result = 37 * result + lastName.hashCode;
    return result;
  }

  // 如果重写了 hashCode，通常应该从新实现 == 操作符。
  @override
  bool operator ==(dynamic other) {
    if (other is! Person) return false;
    Person person = other;
    return (person.firstName == firstName && person.lastName == lastName);
  }
}

void main3() {
  var p1 = Person('Bob', 'Smith');
  var p2 = Person('Bob', 'Smith');
  var p3 = 'not a person';
  assert(p1.hashCode == p2.hashCode);
  assert(p1 == p2);
  assert(p1 != p3);
}

//比较对象
class Line implements Comparable<Line> {
  final int length;
  const Line(this.length);

  @override
  int compareTo(Line other) => length - other.length;
}

void main2() {
  var short = const Line(1);
  var long = const Line(100);
  print(short.compareTo(long) < 0);
}

void main1() {
  print(int.parse('0x42') == 66);
  print(int.parse('42', radix: 16) == 66);
  print(123.456.toStringAsFixed(2) == '123.46');
  //构建一个字符串
  var sb = StringBuffer();
  sb
    ..write('Use a StringBuffer for ')
    ..writeAll(['efficient', 'string', 'creation'], ' ')
    ..write('.');

  var fullString = sb.toString();

  print(fullString);
}

/**
 * dart:async - 异步编程
 * import 'dart:async';
 * 异步编程通常使用回调方法来实现，但是 Dart 提供了其他方案：Future 和 Stream 对象。 
 * 
 * 
 * 
 * Future 类似与 JavaScript 中的 Promise ， 代表在将来某个时刻会返回一个结果。 Stream 类可以用来获取一系列的值，比如，一些列事件。
 */

// await
runUsingAsyncAwait() async {
  // ...
  var entryPoint = await findEntryPoint();
  var exitCode = await runExecutable();
  await flushThenExit();
}

findEntryPoint() {}
runExecutable() {}
flushThenExit() {}
//async 函数能够捕获来自 Future 的异常
runUsingAsyncAwait1() async {
  var entryPoint = await findEntryPoint();
  try {
    var exitCode = await runExecutable();
    await flushThenExit();
  } catch (e) {
    // Handle the error...
  }

  
}
// 使用 catchError() 来处理一些 Future 对象可能抛出的错误或者异常。
// HttpRequest.getString(url).then((String result) {
//   print(result);
// }).catchError((e) {
//   // Handle or ignore the error.
// });
// then().catchError() 组合是 try-catch 的异步版本。
/**
 * 等待多个 Future 有时代码逻辑需要调用多个异步函数， 并等待它们全部完成后再继续执行。 使用 Future.wait() 静态方法管理多个 Future 以及等待它们完成：
 */
// Future deleteLotsOfFiles() async =>  ...
// Future copyLotsOfFiles() async =>  ...
// Future checksumLotsOfOtherFiles() async =>  ...

// await Future.wait([
//   deleteLotsOfFiles(),
//   copyLotsOfFiles(),
//   checksumLotsOfOtherFiles(),
// ]);
// print('Done with all the long steps!');
/**
 * Stream 用来表示一些列数据
 * 异步循环
 */
// void main(List<String> arguments) {
//   // ...
//   FileSystemEntity.isDirectory(searchPath).then((isDir) {
//     if (isDir) {
//       final startingDir = Directory(searchPath);
//       startingDir
//           .list(
//               recursive: argResults[recursive],
//               followLinks: argResults[followLinks])
//           .listen((entity) {
//         if (entity is File) {
//           searchFile(entity, searchTerms);
//         }
//       });
//     } else {
//       searchFile(File(searchPath), searchTerms);
//     }
//   });
// }
//下面是使用 await 表达式和异步 for 循环 (await for) 实现的等价的代码
// Future main(List<String> arguments) async {
//   // ...
//   if (await FileSystemEntity.isDirectory(searchPath)) {
//     final startingDir = Directory(searchPath);
//     await for (var entity in startingDir.list(
//         recursive: argResults[recursive],
//         followLinks: argResults[followLinks])) {
//       if (entity is File) {
//         searchFile(entity, searchTerms);
//       }
//     }
//   } else {
//     searchFile(File(searchPath), searchTerms);
//   }
// }

//监听流数据 listen()
//传递流数据 transform()



/**
 * dart:math - 数学和随机数
 * import 'dart:math';
 * 随机数
 * var random = Random();
random.nextDouble(); // Between 0.0 and 1.0: [0, 1)
random.nextInt(10); // Between 0 and 9.
var random = Random();
random.nextBool(); // true or false //随机布尔值序列：
 */

/**
 * dart:convert - 编解码JSON，UTF-8等
 * import 'dart:convert';
 * 
 * 
 * jsonDecode() 解码 JSON 编码的字符串为 Dart 对象
 * 
 *  jsonEncode() 编码 Dart 对象为 JSON 格式的字符串：
 * 
 * 只有 int， double， String， bool, null, List, 或者 Map 类型对象可以直接编码成 JSON。 List 和 Map 对象进行递归编码。
 */

